package main

import (
	"fmt"
	"github.com/golang/protobuf/proto"
	"gorm.io/driver/sqlite"
	"gorm.io/gorm"
	tree "gorm_transaction/api/tree/v1" // Import the generated protobuf package
	"io/ioutil"
	"log"
)

/*
下面的代码将连接到SQLite数据库并创建一个名为tree_nodes的表，
然后将示例数据插入其中。
接下来，它从数据库中查询数据并构建成protobuf消息的形式。
最后，它将根节点序列化为二进制数据并保存到名为data.pb的文件中。

请注意，TreeNode结构用于表示数据库表中的字段，
并且递归函数findNode用于根据ID查找节点。
*/

// TreeNode represents the structure of your database table
type TreeNode struct {
	ID       int64 `gorm:"primaryKey"`
	ParentID int64
}

// Recursive function to find a node by ID
func findNode(node *tree.TreeNode, targetID int64) *tree.TreeNode {
	if node.GetId() == targetID {
		return node
	}

	for _, child := range node.GetChildren() {
		if foundNode := findNode(child, targetID); foundNode != nil {
			return foundNode
		}
	}

	return nil
}

func main() {
	// Connect to the database
	db, err := gorm.Open(sqlite.Open("./tests/tree_nodes_insert/tree.db"), &gorm.Config{})
	if err != nil {
		log.Fatalf("Error connecting to the database: %v", err)
	}

	// Migrate the table if needed
	if err := db.AutoMigrate(&TreeNode{}); err != nil {
		log.Fatalf("Error migrating table: %v", err)
	}

	// Insert some sample data into the database (You can replace this with your actual data retrieval logic)
	db.Create(&TreeNode{ID: 1, ParentID: 0})
	db.Create(&TreeNode{ID: 2, ParentID: 1})
	db.Create(&TreeNode{ID: 3, ParentID: 1})
	db.Create(&TreeNode{ID: 4, ParentID: 2})
	db.Create(&TreeNode{ID: 5, ParentID: 2})
	db.Create(&TreeNode{ID: 6, ParentID: 3})

	// Query all tree_nodes_insert from the database
	var nodes []TreeNode
	if err := db.Find(&nodes).Error; err != nil {
		log.Fatalf("Error querying data: %v", err)
	}

	// Convert the queried data to protobuf messages
	var protobufNodes []*tree.TreeNode
	for _, node := range nodes {
		protobufNodes = append(protobufNodes, &tree.TreeNode{
			Id:       node.ID,
			ParentId: node.ParentID,
		})
	}

	// Create the root node (assuming it is the one with ParentID = 0)
	var rootNode *tree.TreeNode
	for _, node := range protobufNodes {
		if node.ParentId == 0 {
			rootNode = node
			break
		}
	}

	// Set children for each node
	for _, node := range protobufNodes {
		if node.ParentId != 0 {
			parentNode := findNode(rootNode, node.ParentId)
			if parentNode != nil {
				parentNode.Children = append(parentNode.Children, node)
			}
		}
	}

	// Serialize the root node to a binary format
	data, err := proto.Marshal(rootNode)
	if err != nil {
		log.Fatalf("Error marshalling data: %v", err)
	}

	// Save the serialized data to a file
	err = ioutil.WriteFile("./tests/tree_nodes_insert/data.pb", data, 0644)
	if err != nil {
		log.Fatalf("Error saving data to file: %v", err)
	}

	fmt.Println("Data saved to data.pb successfully!")
}
